package org.myOrg.spetrum.spectrumStruct;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import org.myOrg.spetrum.combination.Tuple;
import org.myOrg.spetrum.combination.TupleCase;
import org.myOrg.spetrum.combination.TupleCaseImplement;
import org.myOrg.spetrum.testObject.TestCase;
import org.myOrg.spetrum.testObject.TestCaseImplement;
import org.myOrg.spetrum.testObject.TestSuite;

public class SpetrumSetup {
	private TestSuite rightTestCases;
	private TestSuite wrongTestCases;
	private TupleStructSets tupleManager;
	private int[] param;
	private TestCase rightCase;

	public int[] getParam() {
		return param;
	}

	public boolean isAllTested() {
		return this.tupleManager.getTupleAnalyseStructByIsTested(false).size() == 0;
	}

	public SpetrumSetup(int[] param, TestSuite wrongTestCases,
			TestSuite rightTestCases) {
		this.param = param;
		this.rightTestCases = rightTestCases;
		this.wrongTestCases = wrongTestCases;
		this.init();
	}

	public void init() {
		tupleManager = new TupleStructSets();
		List<Tuple> tuples = this.getCandidateHeadTuple();
		Iterator<Tuple> itrTuple = tuples.iterator();
		while (itrTuple.hasNext()) {
			tupleManager.initHead(itrTuple.next());
		}
		initPassTuple();
		initFailTuple(tuples);
/*		if (this.wrongTestCases.getTestCaseNum() > 0) {
			if (this.wrongTestCases.getAt(0).getLength() <= Spectrum.MAXDEGREE)
				initFailTuple(tuples);
		}*/
	}

	public void initPassTuple() {
		Iterator<TupleAnalyseStruct> struts = tupleManager.iterator();
		while (struts.hasNext()) {
			TupleAnalyseStruct strut = struts.next();
			if (this.isTupleAppearInRightTestCases(strut.getTuple())) {
				strut.setPassOrFail(true);
				strut.setSuspicion(0);
				strut.setTested(true);
			}
		}
	}

	public void initFailTuple(List<Tuple> tuples) {
		Iterator<Tuple> itr = tuples.iterator();
		while (itr.hasNext()) {
			Tuple tuple = itr.next();
			tupleManager.getTupleAnalyseStructByTuple(tuple).setTested(true);
			tupleManager.getTupleAnalyseStructByTuple(tuple).setPassOrFail(
					false);
		}
	}

	public List<Tuple> getCandidateHeadTuple() {
		HashSet<Tuple> result = new HashSet<Tuple>();
		for (int i = 0; i < wrongTestCases.getTestCaseNum(); i++) {
			TestCase wrongCase = wrongTestCases.getAt(i);
			TupleCase tupleCase = new TupleCaseImplement();
			int degree =  wrongCase.getLength();
			/*int degree = wrongCase.getLength() < Spectrum.MAXDEGREE ? wrongCase
					.getLength() : Spectrum.MAXDEGREE;*/
			List<Tuple> tuples = tupleCase.getTuplesFromCase(wrongCase, degree);
			result.addAll(tuples);
		}
		return new ArrayList<Tuple>(result);

	}

	public boolean isTupleAppearInRightTestCases(Tuple tuple) {
		// TODO Auto-generated method stub
		for (int i = 0; i < rightTestCases.getTestCaseNum(); i++) {
			if (rightTestCases.getAt(i).containsOf(tuple))
				return true;
		}
		return false;
	}

	public TestCase generateOneRightTestCase() {
		// TODO Auto-generated method stub
		if (rightCase == null) {
			rightCase = new TestCaseImplement(param.length);
			for (int i = 0; i < param.length; i++) {
				for (int j = 0; j < param[i]; j++) {
					if (!isWrongCaseContainElement(i, j)) {
						rightCase.set(i, j);
						break;
					}
				}
			}
		}
		return rightCase;
	}

	private boolean isWrongCaseContainElement(int index, int value) {
		boolean result = false;
		for (int i = 0; i < this.wrongTestCases.getTestCaseNum(); i++) {
			if (wrongTestCases.getAt(i).getAt(index) == value) {
				result = true;
				break;
			}
		}
		return result;
	}

	/**
	 * @return the tupleManager
	 */
	public TupleStructSets getTupleManager() {
		return tupleManager;
	}

	public void clear() {
		this.tupleManager.clear();
		this.wrongTestCases.clear();
		this.rightTestCases.clear();
		this.rightCase = null;
		this.param = null;
	}

}
